package com.ltu.payment;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Date;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.dom4j.DocumentException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSONObject;
import com.github.binarywang.wxpay.service.WxPayService;
import com.ltu.base.State;
import com.ltu.domain.mp_entity.PayRecord;
import com.ltu.domain.mp_entity.customize.CompanyEntity;
import com.ltu.mapper.PayRecordMapper;
import com.ltu.mapper.customize.CompanyMapper;
import com.ltu.payment.config.WxAppPayConfig;
import com.ltu.payment.interfaces.PayOrderInterface;
import com.ltu.payment.util.SignUtils;
import com.ltu.payment.util.XmlUtils;
import com.ltu.util.exception.ApiException;
import com.ltu.util.http.HttpPostUtil;
import lombok.extern.slf4j.Slf4j;


/**  
 * @Description: 常规的微信支付
 * @author: 若尘  
 * @date 2018年12月28日 下午2:15:47
 * @version V1.0  
 */
@Component("myWxPayServices")
@Slf4j
public class MyWxPayServices implements PayOrderInterface{

	@Value("${wx.pay.notifyUrl}")
	private String notifyUrl;	
	@Value("${payInfo.test}")
    private Integer PayTest = 1;
	@Autowired
	private  CompanyEntity wxMaMiniAppCfg; //小程序配置

	
	
	@Autowired
	PayRecordMapper  payRecordMapper;
	/**
	 * 微信小程序支付
	 * @param payRecord
	 * @param openid
	 * @param ip
	 * @return
	 */
	public  JSONObject   placeOrder(PayRecord payRecord,String openid,String ip  ){
		Integer total_fee = payRecord.getPayMoney();
		SortedMap<String,Object>   param=new TreeMap<>();
		param.put("appid",wxMaMiniAppCfg.getAppId());  
		param.put("mch_id",wxMaMiniAppCfg.getMchId());
		String nonce_str= String.valueOf(new Date().getTime());
		param.put("nonce_str", nonce_str);
		param.put("body", payRecord.getPayName());//商品描述
		param.put("out_trade_no",payRecord.getOrderNo());//订单号(PAY*)
		param.put("total_fee", ""+total_fee);//交易金额  单位：分
		if(PayTest==1 || total_fee<=0) 
			param.put("total_fee", 1);//交易金额  单位：分
		param.put("spbill_create_ip", ip);
		param.put("notify_url",  notifyUrl);//回调地址
	    param.put("trade_type", "JSAPI");
	    param.put("openid", openid);
	     //转QuseryString字符串
	   String xmlStr=  XmlUtils.paramSort(param,wxMaMiniAppCfg.getMchKeyApi2());  
	   log.info("\n 拉起微信收银台参数：" + xmlStr);
		String resultStr=	HttpPostUtil.sendPost(WxAppPayConfig.WxPayMent, xmlStr);
		
		log.info("本次下单结果："+resultStr);
		if(StringUtils.isBlank(resultStr)){
			throw new ApiException("请求异常");
		}
		JSONObject	  resultMap=new JSONObject();	
		Map<String,String> resultMap1=null;
			 try {
				resultMap1=	XmlUtils.toMap(resultStr.getBytes(), "utf-8");
			
			 JSONObject result=(JSONObject) JSONObject.toJSON(resultMap1);
			
			StringBuilder subStr = new StringBuilder("");
			if (!result.get("return_code").equals("SUCCESS")) {
				subStr.append("\n 通信失败,");
				subStr.append(" \n 请求状态：");
				subStr.append(result.get("return_code"));
				subStr.append("\t ,错误描述：");
				subStr.append(result.get("return_msg"));
				log.error(subStr.toString());
				payRecord.setIsExpire((byte)1);//失效
				payRecord.setStatus((byte) -1);//错误状态
				payRecord.setStatusDesc(subStr.toString());
				throw new ApiException(State.CODE_FAILED,subStr.toString());
			} else {
				if (result.get("result_code").equals("SUCCESS")) {
					  String prepay_id = result.getString("prepay_id");
					  resultMap=SignUtils.createPayParams(wxMaMiniAppCfg.getAppId(), nonce_str, nonce_str, prepay_id,wxMaMiniAppCfg.getMchKeyApi2());
					 //拉起收银成功状态改为正在支付
					  payRecord.setStatus((byte) 2);
					  payRecord.setStatusDesc("拉起收银台成功,正在支付...");
				} else {
					log.error(resultStr);    
					subStr.append("\n 拉起微信官方支付失败：");
					subStr.append(result.getString("result_code"));
					subStr.append(" \n 通信状态：");
					subStr.append(result.get("return_code"));
					subStr.append("\t ,通信描述：");
					subStr.append(result.get("return_msg"));
					subStr.append("\t ,错误码：");
					subStr.append(result.get("err_code"));
					subStr.append("\t ,错误描述：");
					subStr.append(result.get("return_msg"));
					subStr.append("\t ,系统错误描述：");
					subStr.append(result.get("err_code_des"));
					log.error(" 拉起微信官方支付失败：\n" + resultStr);
					payRecord.setIsExpire((byte)1);//失效
					payRecord.setStatus((byte) -1);//错误状态
					payRecord.setStatusDesc(subStr.toString());
					throw new ApiException(State.CODE_FAILED,subStr.toString());
				}
			}
			 } catch (DocumentException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
			}finally{
				payRecordMapper.updateById(payRecord);
			}
		 return resultMap;
	}
	
	/**
	 * 微信APP支付
	 */
	@Override
	public JSONObject placeOrderByApp(PayRecord payRecord,  String ip) {
		Integer total_fee = payRecord.getPayMoney();
		SortedMap<String,Object>   param=new TreeMap<>();
//		param.put("appid", appId);  
//		param.put("mch_id",mchId);
		String nonce_str= String.valueOf(new Date().getTime());
		param.put("nonce_str", nonce_str);
		param.put("body", payRecord.getPayName());//商品描述
		param.put("out_trade_no",payRecord.getOrderNo());//订单号(PAY*)
		param.put("total_fee", ""+total_fee);//交易金额  单位：分
		if(PayTest==1) 
			param.put("total_fee", 1);//交易金额  单位：分
		param.put("spbill_create_ip", ip);
		param.put("notify_url",notifyUrl );//回调地址
	    param.put("trade_type", "APP");
	     //签名
//	   String xmlStr=  XmlUtils.paramSort(param,mchKey);  
	   
//	   System.out.println("\n 请求的xml参数为：" + xmlStr);
		String resultStr=	HttpPostUtil.sendPost(WxAppPayConfig.WxPayMent, "xmlStr");
		
		log.info("本次下单结果："+resultStr);
		if(StringUtils.isBlank(resultStr)){
			throw new ApiException("请求异常");
		}
		JSONObject	  resultJson=new JSONObject();	
		Map<String,String> resultMap1=null;
			 try {
				resultMap1=	XmlUtils.toMap(resultStr.getBytes(), "utf-8");
			
			 JSONObject result=(JSONObject) JSONObject.toJSON(resultMap1);
			
			StringBuilder subStr = new StringBuilder("");
			if (!result.get("return_code").equals("SUCCESS")) {
				subStr.append("\n 通信失败,");
				subStr.append(" \n 请求状态：");
				subStr.append(result.get("return_code"));
				subStr.append("\t ,错误描述：");
				subStr.append(result.get("return_msg"));
				log.error(subStr.toString());
				payRecord.setIsExpire((byte)1);//失效
				payRecord.setStatus((byte) -1);//错误状态
				payRecord.setStatusDesc(subStr.toString());
				throw new ApiException(State.CODE_FAILED,subStr.toString());
			} else {
				if (result.get("result_code").equals("SUCCESS")) {
					  String prepay_id = result.getString("prepay_id");
//					  resultJson.put("appid",  appId);
//					  resultJson.put("partnerid",mchId ); 
					  resultJson.put("prepayid", prepay_id); 
					  resultJson.put("package", "Sign=WXPay");
					  resultJson.put("noncestr", nonce_str);
					  resultJson.put("timestamp", nonce_str);
//					  SignUtils.getSignByWxApp(resultJson,mchKey);
					  //拉起收银成功状态改为正在支付
					  payRecord.setStatus((byte) 2);
					  payRecord.setStatusDesc("拉起收银台成功,正在支付...");
				} else {
					log.error(resultStr);    
					subStr.append("\n 拉起微信官方支付失败：");
					subStr.append(result.getString("result_code"));
					subStr.append(" \n 通信状态：");
					subStr.append(result.get("return_code"));
					subStr.append("\t ,通信描述：");
					subStr.append(result.get("return_msg"));
					subStr.append("\t ,错误码：");
					subStr.append(result.get("err_code"));
					subStr.append("\t ,错误描述：");
					subStr.append(result.get("return_msg"));
					subStr.append("\t ,系统错误描述：");
					subStr.append(result.get("err_code_des"));
					log.error(" 拉起微信官方支付失败：\n" + resultStr);
					payRecord.setIsExpire((byte)1);//失效
					payRecord.setStatus((byte) -1);//错误状态
					payRecord.setStatusDesc(subStr.toString());
					throw new ApiException(State.CODE_FAILED,subStr.toString());
				}
			}
			 } catch (DocumentException e) {
					// TODO Auto-generated catch block
					payRecord.setIsExpire((byte)1);//失效
					payRecord.setStatus((byte) -1);//错误状态
					payRecord.setStatusDesc(e.getMessage());
					e.printStackTrace();
			}finally{
				payRecordMapper.updateById(payRecord);
			}
		 return resultJson;
	}

}

